<template>
  <div class="detail-table" id="applied-list-expend">
    <Button type="info" :size="table.btnSize" @click="batchEdit()" :disabled="table.batch.edit.length <=0 || table.selection.length <= 0">
      <font-awesome-icon icon="edit"/>
      批量修改
    </Button>
    <span style="color: #ed4014; margin-left: 10px;" v-if="table.batch.edit.length <=0 || table.selection.length <= 0">
      勾选<span v-if="table.selection.length <= 0">&nbsp;子实验项目(表格左侧正方形复选框)</span>
      <span v-if="table.batch.edit.length <=0 && table.selection.length <= 0">&nbsp;以及</span>
      <span v-if="table.batch.edit.length <=0">&nbsp;需修改信息(表格头部正方形复选框)</span>&nbsp;后方可批量修改
    </span>
    <Table class="mt-10"
           :border="table.showBorder"
           :stripe="table.showStripe"
           :show-header="table.showHeader"
           :height="table.fixedHeader ? table.height : ''"
           :size="table.size"
           :data="table.data"
           :columns="table.columns"
           :loading="table.loading"
           :disabledHover="table.disabledHover"
           :highlight-row="table.highlightRow"
           @on-row-click="onRowClick"
           @on-selection-change="onSelectionChange">
      <template slot-scope="{ row, index }" slot="laboratory">
        <span v-for="(item, index) in row.classroom" :key="index">
          <span v-if="item.institute">{{ item.institute }}&nbsp; - &nbsp;<br /></span>{{ item.name }}&nbsp; - &nbsp;<br />{{ item.code }}
          <Divider v-if="index !== row.classroom.length - 1" style="margin-top: 10px; margin-bottom: 10px;"/>
        </span>
      </template>
      <template slot-scope="{ row, index }" v-if="row.expType.content === 'TRAINING'" slot="expTime">
        <span v-for="(item, index) in row.trainingExpTime" :key="index">
          {{ item.dates.join(' ~ ') }}
          <span v-if="typeof item.haveClassOnWeekend !== 'undefined'">
            <br />
            （周末{{ item.haveClassOnWeekend ? '' : '不' }}上课）
          </span>
        </span>
      </template>
      <template v-if="showActionColumn" slot-scope="{ row, index }" slot="action">
        <div :style="{pointerEvents: row.deleting ? 'none' : 'auto', paddingTop: '5px', paddingBottom: '5px'}">
          <Button type="primary" :size="table.btnSize" @click="edit(row)">
            <font-awesome-icon icon="edit"/>
            修改
          </Button>
          <Poptip
            confirm
            title="确定删除该子实验项目吗？"
            placement="top"
            class="text-left"
            :options="popperOpts"
            @on-ok="confirmDelExp(row)">
            <Button class="mt-10" :size="table.btnSize" type="warning" :loading="row.deleting">
              <font-awesome-icon icon="trash-alt" v-if="!row.deleting"/>
              删除
            </Button>
          </Poptip>
        </div>
      </template>
    </Table>
    <div class="modal-container">
      <Modal width='95'
            v-model="modal.save.show"
            footer-hide @on-ok="modal.save.show = false"
            @on-cancel="closeSaveModal"
            class="mb-50-modal">
        <p slot="header" class="text-center">{{ modal.save.title }}</p>
        <div>
          <save-course-exp
            v-if="modal.save.show && modal.save.exp_type === 'COURSE'"
            :fieldsetTitle="modal.save.fieldsetTitle"
            :app_code="modal.save.app_code"
            :sid="modal.save.sid"
            :expIndex="modal.save.expIndex"
            :editSingle="modal.save.editSingle"
            v-on:failFillFrom="failFillFrom"
            v-on:saveSuccess="saveSuccess"
          ></save-course-exp>
          <save-training-exp
            v-if="modal.save.show && modal.save.exp_type === 'TRAINING'"
            :fieldsetTitle="modal.save.fieldsetTitle"
            :app_code="modal.save.app_code"
            :sid="modal.save.sid"
            :expIndex="modal.save.expIndex"
            :editSingle="modal.save.editSingle"
            v-on:failFillFrom="failFillFrom"
            v-on:saveSuccess="saveSuccess"
          ></save-training-exp>
        </div>
      </Modal>
      <Modal width='90'
            v-model="modal.batch.show"
            footer-hide @on-ok="modal.batch.show = false"
            @on-cancel="closeSaveModal"
            class="mb-50-modal">
        <p slot="header" class="text-center">{{ modal.batch.title }}</p>
        <div>
          <save-course-exp-batch
            v-if="modal.batch.show && modal.batch.exp_type === 'COURSE'"
            :app_code="modal.batch.app_code"
            :selection="modal.batch.selection"
            :beModifiedItem="modal.batch.beModifiedItem"
            v-on:failFillFrom="failFillFrom"
            v-on:saveSuccess="saveSuccess"
          ></save-course-exp-batch>
          <save-training-exp-batch
            v-if="modal.batch.show && modal.batch.exp_type === 'TRAINING'"
            :app_code="modal.batch.app_code"
            :selection="modal.batch.selection"
            :beModifiedItem="modal.batch.beModifiedItem"
            v-on:failFillFrom="failFillFrom"
            v-on:saveSuccess="saveSuccess"
          ></save-training-exp-batch>
        </div>
      </Modal>
    </div>
  </div>
</template>

<script>
import { getAppliedFormDetail, deleteSingleExps } from '@/api/applied-form-mgmt'
import { activeTableMove } from '@/libs/tools'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faEdit, faTrashAlt } from '@fortawesome/free-solid-svg-icons'
import SaveCourseExp from '_c/save-course-exp/save-course-exp'
import SaveCourseExpBatch from '_c/save-course-exp-batch/save-course-exp-batch'
import SaveTrainingExp from '_c/save-training-exp/save-training-exp'
import SaveTrainingExpBatch from '_c/save-training-exp-batch/save-training-exp-batch'
library.add(faEdit)
library.add(faTrashAlt)
export default {
  name: 'AppliedListExpend',
  components: {
    'save-course-exp': SaveCourseExp,
    'save-course-exp-batch': SaveCourseExpBatch,
    'save-training-exp': SaveTrainingExp,
    'save-training-exp-batch': SaveTrainingExpBatch
  },
  props: {
    row: {
      type: Array
    },
    // 申请表code
    code: {
      type: String,
      default: ''
    },
    // 显示操作列
    showActionColumn: {
      type: Boolean,
      default: false
    },
    // 显示selection列
    showSelectionColumn: {
      type: Boolean,
      default: false
    },
    prefixClass: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      expType: null,
      table: {
        showBorder: true,
        showStripe: false,
        showHeader: true,
        fixedHeader: true,
        height: 600,
        disabledHover: true,
        size: 'small',
        selection: [],
        currRowIndex: '',
        loading: false,
        btnSize: 'small',
        batch: {
          edit: []
        },
        columns: [
          {
            type: 'selection',
            width: 40,
            align: 'center'
          }, {
            title: '实验编号',
            key: 'expIndex',
            width: 40,
            align: 'center',
            render: (h, params) => {
              return h('span', params.row.expIndex.content)
            },
            className: 'row-combined'
          }, {
            title: '实验名称',
            key: 'title',
            minWidth: 150,
            align: 'center',
            render: (h, params) => {
              return h('span', params.row.title.content || '无')
            },
            renderHeader: (h, params) => {
              return this.renderBatchEditHeader(h, params)
            },
            className: 'row-combined'
          }, {
            title: '实验类型',
            key: 'type',
            width: 70,
            align: 'center',
            render: (h, params) => {
              return h('span', params.row.type.content || '无')
            },
            renderHeader: (h, params) => {
              return this.renderBatchEditHeader(h, params, true)
            },
            className: 'row-combined'
          }, {
            title: '实验时间',
            align: 'center',
            children: [
              {
                title: '周次',
                key: 'sweek',
                width: 50,
                renderHeader: (h, params) => {
                  return this.renderBatchEditHeader(h, params, true)
                },
                className: 'row-combined',
                align: 'center'
              }, {
                title: '星期',
                key: 'sdate',
                width: 50,
                renderHeader: (h, params) => {
                  return this.renderBatchEditHeader(h, params, true)
                },
                className: 'row-combined',
                align: 'center'
              }, {
                title: '节次',
                key: 'section',
                width: 90,
                renderHeader: (h, params) => {
                  return this.renderBatchEditHeader(h, params, true)
                },
                align: 'center',
                className: 'row-combined',
                render: (h, params) => {
                  return h('span', params.row.section.join('、') || '无')
                }
              }
            ]
          }, {
            title: '实验室',
            slot: 'laboratory',
            key: 'classroom',
            minWidth: 160,
            renderHeader: (h, params) => {
              return this.renderBatchEditHeader(h, params)
            },
            align: 'center',
            className: 'row-combined'
          }, {
            title: '计划学时',
            key: 'planHours',
            width: 40,
            align: 'center',
            className: 'row-combined',
            renderHeader: (h, params) => {
              return this.renderBatchEditHeader(h, params, true)
            },
            render: (h, params) => {
              return h('span', params.row.planHours.content || '无')
            }
          }, {
            title: '实际学时',
            key: 'actualHours',
            width: 40,
            align: 'center',
            className: 'row-combined',
            renderHeader: (h, params) => {
              return h('div', [
                h('br'),
                h('span', '实际学时')
              ])
            },
            render: (h, params) => {
              return h('span', params.row.actualHours.content || '无')
            }
          }, {
            title: '耗材需求',
            key: 'resources',
            minWidth: 100,
            align: 'center',
            className: 'row-combined',
            renderHeader: (h, params) => {
              return this.renderBatchEditHeader(h, params)
            },
            render: (h, params) => {
              return h('span', params.row.resources.content || '无')
            }
          }, {
            title: '系统需求',
            key: 'system',
            minWidth: 100,
            align: 'center',
            className: 'row-combined',
            renderHeader: (h, params) => {
              return this.renderBatchEditHeader(h, params)
            },
            render: (h, params) => {
              return h('span', params.row.system.content || '无')
            }
          }, {
            title: '软件需求',
            key: 'software',
            minWidth: 100,
            align: 'center',
            className: 'row-combined',
            renderHeader: (h, params) => {
              return this.renderBatchEditHeader(h, params)
            },
            render: (h, params) => {
              return h('span', params.row.software.content || '无')
            }
          }, {
            title: '操作',
            key: 'action',
            slot: 'action',
            width: 85,
            align: 'center',
            className: 'row-combined'
          }
        ],
        data: [],
        highlightRow: false,
        selectedRows: []
      },
      modal: {
        save: {
          show: false,
          exp_type: 'COURSE',
          fieldsetTitle: '',
          title: '修改实验项目',
          app_code: null,
          sid: null,
          expIndex: null,
          editSingle: true
        },
        batch: {
          show: false,
          exp_type: 'COURSE',
          title: '修改实验项目',
          app_code: null,
          selection: [],
          beModifiedItem: []
        }
      },
      popperOpts: {
        modifiers: {
          preventOverflow: {
            boundariesElement: 'scrollParent',
            enabled: false
          },
          hide: {
            enabled: false
          }
        }
      }
    }
  },
  methods: {
    handleTableData (data) {
      let tempData = []
      data.expBaseInfoItems.forEach((item, eIndex) => {
        this.expType = data.exp_type
        if (data.exp_type === 'COURSE' && item.expTimeItemsCourse && item.expTimeItemsCourse.length > 0) {
          let tempMap = new Map()
          item.expTimeItemsCourse.forEach((c, cIndex) => {
            if (!tempMap.has(c.index)) {
              tempMap.set(c.index, {
                sweek: c.expItemTime.sweek,
                sdate: c.expItemTime.sdate,
                section: new Set().add(c.expItemTime.section),
                classroom: new Set().add(JSON.stringify(c.classroom))
              })
            } else {
              tempMap.get(c.index).section.add(c.expItemTime.section)
              tempMap.get(c.index).classroom.add(JSON.stringify(c.classroom))
            }
          })
          item.expTimeItemsCourse = Array.from(tempMap)
          item.expTimeItemsCourse.forEach((c, cIndex) => {
            let obj = {
              expType: {
                content: data.exp_type,
                rowSpan: 1,
                cellShow: false
              },
              appCode: data.app_code
            }
            obj.expIndex = {
              content: eIndex + 1,
              rowSpan: cIndex === 0 ? item.expTimeItemsCourse.length : 1,
              cellShow: cIndex === 0
            }
            obj.sid = item.sid
            obj.title = {
              content: item.title,
              rowSpan: cIndex === 0 ? item.expTimeItemsCourse.length : 1,
              cellShow: cIndex === 0
            }
            obj.type = {
              content: item.type,
              rowSpan: cIndex === 0 ? item.expTimeItemsCourse.length : 1,
              cellShow: cIndex === 0
            }
            obj.actualHours = {
              content: item.actual_hours,
              rowSpan: cIndex === 0 ? item.expTimeItemsCourse.length : 1,
              cellShow: cIndex === 0
            }
            obj.planHours = {
              content: item.plan_hours,
              rowSpan: cIndex === 0 ? item.expTimeItemsCourse.length : 1,
              cellShow: cIndex === 0
            }
            obj.resources = {
              content: item.resources,
              rowSpan: cIndex === 0 ? item.expTimeItemsCourse.length : 1,
              cellShow: cIndex === 0
            }
            obj.software = {
              content: item.software,
              rowSpan: cIndex === 0 ? item.expTimeItemsCourse.length : 1,
              cellShow: cIndex === 0
            }
            obj.system = {
              content: item.system,
              rowSpan: cIndex === 0 ? item.expTimeItemsCourse.length : 1,
              cellShow: cIndex === 0
            }
            obj = Object.assign({
              tIndex: cIndex,
              sweek: c[1].sweek,
              sdate: c[1].sdate,
              section: Array.from(c[1].section),
              classroom: Array.from(c[1].classroom).map(cr => { return JSON.parse(cr) })
            }, obj)
            obj.action = {
              rowSpan: cIndex === 0 ? item.expTimeItemsCourse.length : 1,
              cellShow: cIndex === 0
            }
            tempData.push(obj)
          })
        } else if (data.exp_type === 'TRAINING' && item.expTimeItemsTrain && item.expTimeItemsTrain.length > 0) {
          item.expTimeItemsTrain.forEach((c, cIndex) => {
            let obj = {
              expType: {
                content: data.exp_type,
                rowSpan: 1,
                cellShow: false
              },
              appCode: data.app_code
            }
            obj.expIndex = {
              content: eIndex + 1,
              rowSpan: cIndex === 0 ? item.expTimeItemsTrain.length : 1,
              cellShow: cIndex === 0
            }
            obj.sid = item.sid
            obj.title = {
              content: item.title,
              rowSpan: cIndex === 0 ? item.expTimeItemsTrain.length : 1,
              cellShow: cIndex === 0
            }
            obj.type = {
              content: item.type,
              rowSpan: cIndex === 0 ? item.expTimeItemsTrain.length : 1,
              cellShow: cIndex === 0
            }
            obj.actualHours = {
              content: item.actual_hours,
              rowSpan: cIndex === 0 ? item.expTimeItemsTrain.length : 1,
              cellShow: cIndex === 0
            }
            obj.planHours = {
              content: item.plan_hours,
              rowSpan: cIndex === 0 ? item.expTimeItemsTrain.length : 1,
              cellShow: cIndex === 0
            }
            obj.resources = {
              content: item.resources,
              rowSpan: cIndex === 0 ? item.expTimeItemsTrain.length : 1,
              cellShow: cIndex === 0
            }
            obj.software = {
              content: item.software,
              rowSpan: cIndex === 0 ? item.expTimeItemsTrain.length : 1,
              cellShow: cIndex === 0
            }
            obj.system = {
              content: item.system,
              rowSpan: cIndex === 0 ? item.expTimeItemsTrain.length : 1,
              cellShow: cIndex === 0
            }
            obj = Object.assign({
              trainingExpTime: [{
                dates: c.dates,
                haveClassOnWeekend: c.haveClassOnWeekend
              }],
              tIndex: cIndex,
              classroom: c.classroom
            }, obj)
            obj.action = {
              rowSpan: cIndex === 0 ? item.expTimeItemsTrain.length : 1,
              cellShow: cIndex === 0
            }
            tempData.push(obj)
          })
        }
      })
      return tempData
    },
    getTableColumns (columns) {
      let tableColumns = []
      columns.forEach(item => {
        if (!item.children) {
          tableColumns.push(item)
        }
        if (item.children && item.children.length > 0) {
          tableColumns = tableColumns.concat(this.getTableColumns(item.children))
        }
      })
      return tableColumns
    },
    // 在多选模式下有效，只要选中项发生变化时就会触发
    onSelectionChange (selection) {
      this.table.selection = selection
    },
    // 修改单个实验
    edit (row) {
      this.modal.save = Object.assign(this.modal.save, {
        show: true,
        exp_type: row.expType.content,
        title: '修改单个实验信息',
        fieldsetTitle: '实验' + row.expIndex.content + '基本信息',
        app_code: row.appCode,
        sid: row.sid,
        expIndex: row.expIndex.content,
        editSingle: true
      })
    },
    // 确认删除
    confirmDelExp (row) {
      this.$nextTick(() => {
        this.$set(this.table.data[this.table.currRowIndex], 'deleting', true)
        deleteSingleExps(row.appCode, [row.sid]).then(response => {
          let res = response.data
          this.$set(this.table.data[this.table.currRowIndex], 'deleting', false)
          if (res.code === 1) {
            this.$Notice.success({
              title: '提示',
              desc: '删除所选子实验成功'
            })
            this.$emit('refresh')
          } else {
            this.$Notice.error({
              title: '提示',
              desc: '删除所选子实验失败！' + res.info
            })
          }
        }).catch(error => {
          console.log(error)
          this.$set(this.table.data[this.table.currRowIndex], 'deleting', false)
          this.$Notice.error({
            title: '提示',
            desc: '删除所选子实验失败，请重试！' + error
          })
        })
      })
    },
    // 关闭 新增 / 修改 申请表的Modal的回调函数
    closeSaveModal () {
      this.$nextTick(() => {
        // 全局配置notice组件的属性
        this.$Notice.config({
          top: window.innerHeight / 3
        })
      })
    },
    // 修改实验填充表单失败
    failFillFrom (info) {
      this.modal.save.show = false
      this.$Notice.error({
        title: '获取实验信息失败，请稍后重试',
        desc: info
      })
    },
    // 成功 新增 / 修改 实验
    saveSuccess (isModified) {
      this.modal.save.show = false
      this.modal.batch.show = false
      this.$nextTick(() => {
        this.$Notice.success({
          title: '提交成功',
          desc: isModified ? '修改实验信息成功' : '新增实验成功'
        })
        this.$emit('refresh')
      })
    },
    // 单击某一行时触发
    onRowClick (row, index) {
      this.table.currRowIndex = index
    },
    // 渲染带checkbox的表头
    renderBatchEditHeader (h, params, needBr) {
      return h('div', [
        h('CheckboxGroup', {
          on: {
            'on-change': value => {
              this.handleBatchEditArray(value, params.column.key)
            }
          }
        }, [
          h('Checkbox', {
            props: {
              label: params.column.key
            },
            style: {
              marginRight: '0'
            }
          }, needBr ? [
            h('br'),
            h('span', params.column.title)
          ] : params.column.title)
        ])
      ])
    },
    // 点击表头checkbox的回调函数
    handleBatchEditArray (value, key) {
      if (value.length > 0) {
        if (this.table.batch.edit.indexOf(value[0]) < 0) {
          this.table.batch.edit.push(value[0])
        }
      } else {
        let index = this.table.batch.edit.indexOf(key)
        if (index > -1) {
          this.table.batch.edit.splice(index, 1)
        }
      }
    },
    // 批量修改处理事件
    batchEdit () {
      this.modal.batch = {
        show: true,
        exp_type: this.expType,
        title: '批量修改实验项目信息',
        app_code: this.code,
        selection: this.table.selection,
        beModifiedItem: this.table.batch.edit
      }
    }
  },
  async created () {
    this.table.loading = true
    if (!this.showActionColumn) {
      this.table.columns.pop()
    }
    if (!this.showSelectionColumn) {
      this.table.columns.shift()
    }
    let res = {
      data: ''
    }
    if (!this.row[0]) {
      try {
        let response = await getAppliedFormDetail(this.code)
        response = response.data
        if (response.code) {
          res.data = response.data
        } else {
          this.table.loading = false
          this.table.data = []
          this.$Notice.error({
            title: '列表加载失败',
            desc: '实验课信息登记表加载失败！' + res.info + '请重试！'
          })
          return false
        }
      } catch (error) {
        this.table.loading = false
        this.table.data = []
        this.$Notice.error({
          title: '列表加载失败',
          desc: '实验课信息登记表加载失败！请重试！' + error
        })
        console.log(error)
      }
    } else {
      res.data = this.row[0]
    }
    if (res.data.exp_type === 'TRAINING') {
      let expTimeColumn = this.showSelectionColumn ? this.table.columns.slice(4, 5) : this.table.columns.slice(3, 4)
      expTimeColumn[0].children = [{
        title: '日期',
        slot: 'expTime',
        key: 'trainingExpTime',
        width: 150,
        renderHeader: (h, params) => {
          return this.renderBatchEditHeader(h, params)
        },
        className: 'row-combined',
        align: 'center'
      }]
    }
    this.table.data = this.handleTableData(res.data)
    let columns = this.getTableColumns(this.table.columns)
    this.$nextTick(() => {
      document.querySelectorAll((this.prefixClass ? this.prefixClass + ' ' : '') + '#applied-list-expend.detail-table .ivu-table-body td.row-combined').forEach((item, index) => {
        let row = this.table.data[Math.floor(index / (this.showSelectionColumn ? columns.length - 1 : columns.length))]
        let cell = columns[index % (this.showSelectionColumn ? columns.length - 1 : columns.length) + (this.showSelectionColumn ? 1 : 0)].key
        if (Object.prototype.toString.call(row[cell]) === '[object Object]') {
          item.setAttribute('rowspan', row[cell].rowSpan || 1)
          item.style.display = row[cell].cellShow ? '' : 'none'
          if (!row[cell].cellShow) {
            item.parentNode.removeChild(item)
          }
        }
      })
      this.table.loading = false
    })
  },
  mounted () {
    this.$nextTick(() => {
      activeTableMove(document.querySelector((this.prefixClass ? this.prefixClass + ' ' : '') + '#applied-list-expend.detail-table .ivu-table-body'))
    })
  }
}
</script>

<style lang="less">
  .detail-table {
    .ivu-table {
      &-tbody {
        .ivu-table-cell {
          padding-top: 10px;
          padding-bottom: 10px;
          font-weight: bold;
        }
      }
    }
  }
  .ivu-table {
    td.ivu-table-expanded-cell {
      padding: 20px;
    }
  }
  .mb-50-modal {
    .ivu-modal {
      margin-bottom: 50px;
    }
  }
</style>
